<template>
  <div id="Index" :class="{maximize: maximize}">
    <div class="topBar">
      <div class="logo" @click="$electron.shell.openExternal('https://www.haicaochat.com/index.html')">
        <Icons :size="40" name="haicao" />海草
      </div>
      <div class="chat_opt">
        <div class="swicth" v-if="status[current_cs]">
          <div @click="setListShow(3)" class="item" :class="{active: status[current_cs].listswitch === 3}">
            <Icons name="qunfayoujian" />
            <span>群发消息</span>
          </div>
          <div @click="setListShow(0)" class="item" :class="{active: status[current_cs].listswitch === 0}">
            <Icons name="xinxi" />
            <span>我的消息</span>
          </div>
          <div @click="setListShow(1)" class="item" :class="{active: status[current_cs].listswitch === 1}">
            <Icons name="yonghu" />
            <span>联系人</span>
          </div>
        </div>
        <div class="statis" v-if="status[current_cs]">
          <div class="item"><span>已沟通</span><b>{{status[current_cs].statis.groupid}}</b></div>
          <div class="item"><span>未沟通</span><b>{{status[current_cs].statis.ungroupid}}</b></div>
          <div class="item"><span>取关</span><b>{{status[current_cs].statis.unsubscribe}}</b></div>
          <div class="item"><span>取关率</span><b>{{((status[current_cs].statis.unsubscribe||0) / ((status[current_cs].statis.subscribe||0) + (status[current_cs].statis.unsubscribe||0)) * 100).toFixed(2) + '%'}}</b></div>
        </div>
      </div>
      <div class="option">
        <div @click="openTaskbox" class="items" title="通知"><Icons name="task" /></div>
        <div @click="refreshPage()" class="items" title="刷新"><Icons name="refresh" /></div>
        <div @click="openSetbox" class="items" title="设置"><Icons name="shezhichilunshebei" /></div>
        <div @click="sendMainEvent('main_min')" class="items" title="最小化"><Icons :size="16" name="font46" /></div>
        <div @click="sendMainEvent('main_hide')" class="items close" title="关闭"><Icons :size="14" name="chenghao" /></div>
      </div>
    </div>
    <div class="contents">
      <div class="kefu_list">
        <div class="addcsuser">
          <span @click="addCsuer"><Icons name="add" />添加客服</span>
        </div>
        <div class="csuser_list">
          <csuserItem @contextmenu.prevent.native="clearCsuser(item)" ref="csuser_item" :clickClose="goOutCsuser" @click.native="selectCsuser(item)" :active="item.cs_id == current_cs" :user="item" v-for="(item, index) in csuser_list" :key="index"
        v-dragging="{ item: item, list: csuser_list, group: 'csuser_list',otherData: 'csuser_list' }"/>
        </div>
      </div>
      <div class="chat_box">
        <chatBox @updataStatus="updataStatus" @clearNewnum="clearNewnum" :current="current_cs" ref="chatbox" />
      </div>
    </div>
    <transition name="fade">
    <div v-show="mask_show" class="maskbox" @click="closeMask"></div>
    </transition>
    <transition name="left">
      <div v-show="task_show" class="taskbox">
        <div class="items" :class="{mass: item.type === 'mass'}" v-for="(item, index) in taskbox.list" :key="index">
          <div class="title">
            群发消息<span>{{item.create_time | formatDate}}</span>
          </div>
          <Progress v-if="item.status" :percent="item.status.done / item.status.total * 100" status="active" hide-info />
          <div class="result" v-if="item.status">
            完成进度：{{item.status.done + '/' + item.status.total}}
          </div>
        </div>
      </div>
      
    </transition>
  </div>
</template>

<script>
import csuserItem from '../../components/csuserItem'
import chatBox from '../../components/chatBox'
import Tips from '../../assets/js/tips.js'
import Wss from '../../assets/js/wss'

var disconnectTips = new Tips({
  msg: '网络连接断开',
  type: 'error'
})
window.disconnectTips = disconnectTips
var checkHeartBeat
export default {
  name: 'Index',
  data: () => {
    return {
      mask_show: false,
      task_show: false,
      status: {
      },
      maximize: false,
      $ws: null,
      taskbox: {
        show: false,
        list: []
      },
      heart_beat: false,
      current_cs: null,
      csuser_list: [
      ],
      socket_list: [
      ]
    }
  },
  watch: {
    async current_cs () {
      for (var i = 0; i < this.csuser_list.length; i++) {
        if (this.csuser_list[i].cs_id === this.current_cs) {
          try {
            var result = await this.$fn.checkLogin(this.csuser_list[i])
            if (result.status !== 1) {
              var isOk = confirm('当前账号已在其他地方登录，是否重新登录！')
              if (isOk) {
                this.rePostLogin()
              }
            }
          } catch (e) {
            console.log(e)
          }
        }
      }
    }
  },
  components: {
    csuserItem,
    chatBox
  },
  async created () {
    window.$In = this
    this.$electron.remote.getCurrentWindow().on('maximize', () => {
      // 窗口最大化
      this.maximize = true
    })
    this.$electron.remote.getCurrentWindow().on('unmaximize', () => {
      // 窗口退出最大化
      this.maximize = false
    })
    var _this = this
    this.$electron.ipcRenderer.on('notice_to_msg', function (event, data) {
      _this.current_cs = data.user.butt_id
      _this.$refs['chatbox'].msgClick({
        id: data.user.user_id,
        num: data.user.new_msg_num,
        openid: data.user.openid
      })
    })
    await new Promise(function (resolve) {
      var ws = new Wss(function () {
        _this.$ws = ws
        resolve()
      })
    })
    this.$ws.onmsg = (event, data) => {
      this.$options.sockets[event] && this.$options.sockets[event](data, this)
    }
    window.$Index = this
    /**
     * 1.获取数据库客服列表 （没有跳转登录）
     */
    try {
      var csuserList = await this.$db.user_login.getUser()
      if (csuserList.length === 0) {
        throw new Error('没有客服登录')
      }
      var newCsuserList = []
      csuserList.forEach((item) => {
        let inNews = false
        newCsuserList.forEach((item1) => {
          if (item1.cs_id === item.cs_id) {
            inNews = true
          }
        })
        if (!inNews) {
          newCsuserList.push(item)
        }
      })
      newCsuserList.sort(function (v1, v2) {
        return v1.sort - v2.sort
      })
      this.csuser_list = newCsuserList
      this.current_cs = newCsuserList[0].cs_id
      for (let i = 0; i < this.csuser_list.length; i++) {
        let loadresult = await this.$refs['chatbox'].loadingRes(this.csuser_list[i].cs_id)
        this.status[this.csuser_list[i].cs_id] = {
          statis: loadresult.data.statis,
          listswitch: loadresult.data.listswitch
        }
        this.$forceUpdate()
      }
    } catch (e) {
      console.log(e)
      this.$electron.ipcRenderer.send('main_hide')
      this.$electron.ipcRenderer.send('login_show')
    }
    // 登录请求成功 加载资源
    this.$electron.ipcRenderer.on('login_success', async (event, data) => {
      var result = await this.loadingRes(data)
      if (result.status === 1) {
        this.csuser_list.push(data)
        this.csuser_list.forEach((item, index) => {
          item.sort = index
        })
        this.$forceUpdate()
        this.$db.user_login.updataUser(this.csuser_list)
        if (this.current_cs === null) this.current_cs = data.cs_id
        this.$db.user_login.setUser(data)
        this.$electron.ipcRenderer.send('load_res_success')
      } else {
        this.$electron.ipcRenderer.send('load_res_error')
      }
    })
    this.$electron.ipcRenderer.on('send_mass_msg', async (event, data) => {
      // 存储任务
      data.type = 'mass'
      try {
        var saveTask = await this.$db.task_list.setTask(data)
        if (saveTask === null) {
          throw new Error('创建群发任务失败')
        }
        this.startMass(saveTask)
      } catch (e) {
        console.log(e)
      }
    })
  },
  mounted () {
    this.$dragging.$on('dragged', ({ value }) => {
      if (value.otherData === 'csuser_list') {
        value.list.forEach((item, index) => {
          item.sort = index
        })
        this.csuser_list = value.list
        this.$forceUpdate()
        this.$db.user_login.updataUser(this.csuser_list)
      }
    })
  },
  methods: {
    // 设置组件状态
    setListShow (index) {
      this.$refs['chatbox'].setListShow(this.current_cs, index)
    },
    // 更新组件状态
    updataStatus (csId, data) {
      this.status[csId] = data
      this.$forceUpdate()
    },
    refreshPage () {
      window.location.reload()
    },
    /**
     * 打开任务列表
     */
    async openTaskbox () {
      this.task_show = !this.task_show
      this.mask_show = !this.mask_show
      if (this.task_show) {
        var taskList = await this.$db.task_list.getTask()
        taskList.sort(function (x, y) {
          return y._index - x._index
        })
        this.taskbox.list = taskList
        this.$forceUpdate()
      }
    },
    sendMainEvent (name) {
      this.$electron.ipcRenderer.send(name)
    },
    /**
     * 选择客服
     */
    selectCsuser (csuser) {
      this.current_cs = csuser.cs_id
      // csuser.msgnum = 0
      // this.$refs['csuser_item'].forEach(function (item) { item.$forceUpdate() })
    },
    /**
     * 清除客服角标
     */
    clearCsuser (csuser) {
      csuser.msgnum = 0
      this.$refs['csuser_item'].forEach(function (item) { item.$forceUpdate() })
    },
    /**
     * 退出客服账号
     */
    async goOutCsuser (csuser) {
      var result = await this.$db.user_login.delUser(csuser.cs_id)
      if (!result) {
        this.$Message.error('退出失败')
        return
      }
      var indexs = null
      this.csuser_list.forEach((item, index) => {
        if (csuser.cs_id === item.cs_id) {
          indexs = index
        }
      })
      if (indexs !== null) {
        // 删除客服列表里面的内容
        this.csuser_list.splice(indexs, 1)
        this.csuser_list.forEach((item, index) => {
          item.sort = index
        })
        this.$forceUpdate()
        this.$db.user_login.updataUser(this.csuser_list)
      }
      // 判断是否还有客服，没有了 跳转到登录页面
      if (this.csuser_list.length <= 0) {
        this.$electron.ipcRenderer.send('main_hide')
        this.$electron.ipcRenderer.send('login_show')
        return
      }
      // 判断是不是当前客服
      if (this.current_cs === csuser.cs_id) {
        this.current_cs = this.csuser_list[0].cs_id
      }
      delete this.$refs['chatbox'].data[csuser.cs_id]
      this.$forceUpdate()
      this.$refs['chatbox'].$forceUpdate()
    },
    /**
     * 加载资源
     */
    async loadingRes (data) {
      if (!this.$refs['chatbox']) return
      var result = await this.$refs['chatbox'].loadingRes(data.info.id)
      return result
    },
    /**
     * 添加客服账号
     */
    addCsuer () {
      this.$electron.ipcRenderer.send('login_show')
    },
    /**
     * 重新登录
     */
    async rePostLogin () {
      var csuser
      for (var i = 0; i < this.csuser_list.length; i++) {
        if (this.csuser_list[i].cs_id === this.current_cs) {
          csuser = this.csuser_list[i]
        }
      }
      var data = {
        username: csuser.info.username,
        pwd: csuser.pwd,
        type: 1002,
        adminLogin: false,
        mobileLogin: false
      }
      try {
        var result = await this.$fn.postLogin(data)
        if (result.status === 1) {
          csuser.key = result.key
          await this.$db.user_login.setUser(csuser)
          this.$refs.chatbox.refresh()
        } else {
          throw new Error('当前账号已在其他地方登录，请重新登录')
        }
      } catch (e) {
        console.log(e)
        this.$Message.error('当前账号已在其他地方登录，请重新登录')
        var index = null
        for (var ij = 0; ij < this.csuser_list.length; ij++) {
          if (this.csuser_list[ij].cs_id === this.current_cs) {
            index = ij
          }
        }
        if (index !== null) {
          this.csuser_list.splice(index, 1)
          this.csuser_list.forEach((item, index) => {
            item.sort = index
          })
          this.$forceUpdate()
          this.$db.user_login.updataUser(this.csuser_list)
        }
      }
    },
    /**
     * 清除角标
     */
    clearNewnum (csid, user) {
      if (user.num) {
        for (var ij = 0; ij < this.csuser_list.length; ij++) {
          if (this.csuser_list[ij].cs_id === csid) {
            this.csuser_list[ij].msgnum -= user.num
            this.csuser_list[ij].msgnum = this.csuser_list[ij].msgnum > 0 ? this.csuser_list[ij].msgnum : 0
            this.$forceUpdate()
            this.$refs['csuser_item'].forEach((item) => { item.$forceUpdate() })
          }
        }
      }
    },
    /**
     * 发送心跳包
     */
    sendHeartBeat () {
      var userList = []
      this.socket_list.forEach((item) => {
        this.csuser_list.forEach((item1) => {
          if (item1.cs_id === item.id) {
            userList.push({
              id: item.id,
              key: item1.key
            })
          }
        })
      })
      this.$ws.emit('heartbeat_new', {
        type: 1002,
        userlist: userList,
        sockerID: this.$ws.sockerID
      })
      checkHeartBeat = setTimeout(() => { // 服务器 60s 没有响应客户端连接
        disconnectTips.hide()
        this.heartBeatError(1001)
      }, 1000 * 60)
    },
    /**
     * 心跳包错误处理
     */
    heartBeatError (type) {
      if (type === 1001) { // 网络超时，提示用户网络超时  并返回到登录页面
        disconnectTips.show()
      }
      this.sendHeartBeat()
    },
    /**
     * 开始群发消息
     */
    async startMass (data) {
      var _result = []
      for (var i = 0; i < data.userlist.length; i++) {
        let _user = data.userlist[i]
        _result[i] = []
        for (var j = 0; j < data.msglist.length; j++) {
          let _msg = data.msglist[j]
          if (_msg.type === 'outline') { // 对应客服的离线消息
            try {
              var sendStatus = await this.$fn.sendOutline(_user)
              if (sendStatus.status !== 1) {
                _result[i][j] = false
              } else {
                _result[i][j] = true
              }
            } catch (e) {
              _result[i][j] = false
            }
          } else if (_msg.type === 'text') {
            var datas = {
              appid: data.csuser.appid,
              content: _msg.text,
              cs_id: data.csuser.id,
              openid: _user,
              send_time: parseInt(Date.now() / 1000),
              type: 'text'
            }
            try {
              var _msgStatus = await this.$fn.sendMassMsgs(datas)
              if (_msgStatus.status !== 1) {
                _result[i][j] = false
              } else {
                _result[i][j] = true
                this.$refs['chatbox'].updataMsgUser(datas)
              }
            } catch (e) {
              console.log(e)
              _result[i][j] = false
            }
          } else if (_msg.type === 'image') {
            var data1 = {
              appid: data.csuser.appid,
              content: _msg.content,
              cs_id: data.csuser.id,
              media_id: _msg.media_id,
              openid: _user,
              send_time: parseInt(Date.now() / 1000),
              type: 'image'
            }
            try {
              var _msgStatus1 = await this.$fn.sendMassMsgs(data1)
              if (_msgStatus1.status !== 1) {
                _result[i][j] = false
              } else {
                _result[i][j] = true
                this.$refs['chatbox'].updataMsgUser(data1)
              }
            } catch (e) {
              console.log(e)
              _result[i][j] = false
            }
          }
        }
        data.status = data.status || {
          total: data.userlist.length,
          done: 0
        }
        data.status.done += 1
        await this.$db.task_list.setTask(data)
      }
    },
    // 关闭遮罩
    closeMask () {
      this.mask_show = false
      this.task_show = false
    },
    // 打开设置窗口
    openSetbox () {
      this.$refs['chatbox'].openSetBox()
      this.$refs['chatbox'].$forceUpdate()
    },
    reRender (msgdata) {
      this.$forceUpdate()
      this.$refs['chatbox'].$forceUpdate()
      this.$refs['chatbox'].sortMsgList(msgdata.cs_id)
      if (this.$refs['chatbox'].$refs['msguser_list']) {
        this.$refs['chatbox'].$refs['msguser_list'].$forceUpdate()
        this.$refs['chatbox'].$refs['msguser_list'].$refs['user_item'].forEach((item) => { item.$forceUpdate() })
      }
      if (this.$refs['chatbox'].$refs['chat_win']) this.$refs['chatbox'].$refs['chat_win'].$forceUpdate()
      this.$refs['csuser_item'].forEach(function (item) { item.$forceUpdate() })
      msgdata && this.$refs['chatbox'].newsMsg(msgdata)
    }
  },
  sockets: {
    test: function (data, self) {
    },
    // socket断开链接
    disconnect: function () {
      disconnectTips.show()
    },
    // socket重连
    reconnect: function () {
      disconnectTips.hide()
    },
    // 链接服务端
    re_connect: function (data, self) {
      self.$ws.sockerID = data.sockerID
      var _isInlist = false
      self.socket_list.forEach((item) => {
        if (item.id === data.user.id) {
          _isInlist = true
        }
      })
      if (!_isInlist) {
        self.socket_list.push(data.user)
      }
      // 发送心跳包
      if (!self.heart_beat) {
        self.sendHeartBeat()
        self.heart_beat = true
      }
    },
    // 心跳包返回
    heartbeat_new (result, self) {
      disconnectTips.hide()
      clearTimeout(checkHeartBeat)
      result.forEach((item) => {
        if (!item.result) {
          // console.log(item.id + '连接异常')
        }
      })
      // 再次执行心跳包
      self.sendHeartBeat()
    },
    // 账号在另一处登录
    remote_logon (user, self) {
      for (var i = self.csuser_list.length - 1; i >= 0; i--) {
        if (self.csuser_list[i].cs_id === user.id) {
          self.$Message.error(`客服账号${self.csuser_list[i].info.nickname}在其他地方登录,请重新登录`)
          self.csuser_list.splice(i, 1)
          self.$forceUpdate()
          break
        }
      }
    },
    // 收到消息
    async sendMsg (msgdata, self) {
      self.$db.chatlog_list.addChatlog(msgdata)
      var config = {}
      try {
        config = await self.$db.config.getConfig()
      } catch (e) {
        config = {
          id: 0,
          notifi_sound: true,
          newmsg_mp3: require('../../assets/audio/2.mp3'),
          subscribe_mp3: require('../../assets/audio/1.mp3'),
          unsubscribe_mp3: require('../../assets/audio/3.mp3')
        }
      }
      var mp3
      if (msgdata.type === 'subscribe') {
        mp3 = config.subscribe_mp3
      } else if (msgdata.type === 'unsubscribe') {
        mp3 = config.unsubscribe_mp3
      } else {
        mp3 = config.newmsg_mp3
      }
      var isNotice = true
      // 1.判断消息客服在不在当前客服列表
      var _cuuser = {}
      var _maguser = {}
      var inCslist = false
      self.csuser_list.forEach((item) => {
        if (parseInt(item.cs_id) === parseInt(msgdata.cs_id)) {
          inCslist = true
          item.msgnum = item.msgnum || 0
          item.msgnum += 1
          _cuuser = item
        }
      })
      if (!inCslist) { // 消息客服不在当前客服列表
        msgdata.info = '消息客服不在当前客服列表'
        self.$fn.addLogs({
          level: 'Warn',
          type: '客户端',
          name: '接收消息',
          result: msgdata
        })
        return
      } else {
        self.$fn.addLogs({
          level: 'Success',
          type: '客户端',
          name: '接收消息',
          result: msgdata
        })
      }
      // 2.判断消息用户是否在消息列表
      var inMsgList = false
      self.$refs['chatbox'].data[msgdata.cs_id].msguser.forEach((item) => {
        if (item.openid === msgdata.openid) {
          inMsgList = true
          item.new_msg_num = item.new_msg_num || 0
          item.new_msg_num += 1
          item.last_butt_msg = self.$fn.maskNewMsg(msgdata)
          item.last_butt_time = parseInt(msgdata.send_time)
          _maguser = item
        }
      })
      if (!inMsgList) {
        var inAllList = false
        self.$refs['chatbox'].data[msgdata.cs_id].alluser.forEach((item) => {
          if (item.openid === msgdata.openid) {
            inAllList = true
            let lastButtMsg = self.$fn.maskNewMsg(msgdata)
            let _user = {
              age: item.age || 0,
              butt_id: item.butt_id,
              headimgurl: item.headimgurl,
              last_butt_msg: lastButtMsg,
              last_butt_time: parseInt(msgdata.send_time),
              new_msg_num: 1,
              name: item.name,
              nickname: item.nickname,
              openid: item.openid,
              phone: item.phone,
              sex: item.sex,
              user_id: item.user_id,
              wechat_num: item.wechat_num
            }
            _maguser = _user
            self.$refs['chatbox'].data[msgdata.cs_id].msguser.push(_user)
            self.$db.user_list.addUser(_user)
          }
        })
        if (!inAllList) {
          let item = await self.$fn.getSqlUser(msgdata.openid)
          self.$refs['chatbox'].data[msgdata.cs_id].alluser.push(item)
          let lastButtMsg = self.$fn.maskNewMsg(msgdata)
          let _user = {
            age: item.age || 0,
            butt_id: item.butt_id,
            headimgurl: item.headimgurl,
            last_butt_msg: lastButtMsg,
            last_butt_time: parseInt(msgdata.send_time),
            new_msg_num: 1,
            name: item.name,
            nickname: item.nickname,
            openid: item.openid,
            phone: item.phone,
            sex: item.sex,
            user_id: item.user_id,
            wechat_num: item.wechat_num
          }
          _maguser = _user
          self.$refs['chatbox'].data[msgdata.cs_id].msguser.push(_user)
          await self.$db.user_list.addUser(_user)
        }
      }
      // 3.判断当前打开的聊天是不是当前消息用户
      if (self.$refs['chatbox'].$refs['chat_win'] && parseInt(self.current_cs) === parseInt(msgdata.cs_id)) {
        // 当前客服
        let _openid = self.$refs['chatbox'].$refs['chat_win'].user.openid
        if (msgdata.openid === _openid) {
          // 当前用于
          let inWin = self.$electron.remote.getCurrentWindow()
          if (!inWin.isFocused()) {
            // 窗口没有焦点，触发底部状态栏闪烁
            self.$electron.ipcRenderer.send('main_flash_frame')
          } else {
            isNotice = false
            _maguser.new_msg_num = 0
            _cuuser.msgnum -= 1
          }
          try {
            self.$refs['chatbox'].$refs['chat_win'].data.chatlog.push(msgdata)
          } catch (e) {
            console.log(e.message)
          }
        }
      }
      // 刷新页面渲染
      if (isNotice) {
        if (config.notifi_sound) {
          let audio = document.createElement('audio')
          audio.src = mp3
          audio.setAttribute('autoplay', 'true')
        }
        self.$electron.ipcRenderer.send('notice_show', {user: _maguser, csuser: _cuuser})
      }
      self.reRender(msgdata)
    }
  }
}
</script>

<style lang="less">
@import './style.less';
</style>
